﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Configuration;

namespace Streambolics
{
    /// <summary>
    ///     Utility class to access and change the path to the App.Config file.
    /// </summary>
    /// <remarks><para>
    ///     This class is based on the CodeProject article http://www.codeproject.com/KB/dotnet/dllappconfig.aspx
    /// </para></remarks>

    public class ConfigurationFile
    {
        private static bool _RecognizedLibVersion = Assembly.GetAssembly (typeof (ConfigurationManager)).GetName ().Version.ToString ().CompareTo ("2.0.0.0") == 0;

        /// <summary>
        ///     The path to the current configuration file.
        /// </summary>

        public static string CurrentFile
        {
            get
            {
                return AppDomain.CurrentDomain.GetData ("APP_CONFIG_FILE").ToString ();
            }
            set
            {
                if (CurrentFile != value)
                {
                    try
                    {
                        if (_RecognizedLibVersion)
                        {
                            AppDomain.CurrentDomain.SetData ("APP_CONFIG_FILE", value);
                            Type InitState = typeof (ConfigurationManager).GetNestedType ("InitState", BindingFlags.NonPublic);
                            if (InitState == null)
                            {
                                throw new Exception ("InitState class not found");
                            }

                            FieldInfo[] InitStateFields = InitState.GetFields ();
                            if (InitStateFields == null)
                            {
                                throw new Exception ("IniState class has no fields");
                            }

                            FieldInfo s_InitState = typeof (ConfigurationManager).GetField ("s_initState", BindingFlags.NonPublic | BindingFlags.Static);
                            if (s_InitState == null)
                            {
                                throw new Exception ("s_initState field not found");
                            }

                            FieldInfo s_configSystem = typeof (ConfigurationManager).GetField ("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static);
                            if (s_configSystem == null)
                            {
                                throw new Exception ("s_configSystem field not found");
                            }

                            s_InitState.SetValue (null, InitStateFields[1].GetValue (null));
                            s_configSystem.SetValue (null, null);
                        }
                        else
                        {
                            throw new Exception ("Requires version 2.0.0.0");
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception ("ERR-xxxxx Can't switch the Application Configuration File to " + value, e);
                    }

                }
            }
        }
    }

    public class TemporaryConfigurationFile : IDisposable
    {
        private string _oldConfig = ConfigurationFile.CurrentFile;

        public TemporaryConfigurationFile (string aFileName)
        {
            ConfigurationFile.CurrentFile = aFileName;
        }

        public void Dispose ()
        {
            ConfigurationFile.CurrentFile = _oldConfig;
        }

    }

}
